اساسيات


الثوابت Constants



فكرة الثوابت المسماة شبية بالمتغيرات حيث يمكننا الوصول اليه الإان قيم الثوابت لا يمكن تغيرها طيلة زمن التشغيل ، واغلب المبرمجين يستخدمون الثوابت بسبب تعدل الثابت لاحقاً بدلاً من تغير كل قيمة على حد في كل البرنامج حيث يتم تغير تعليمة واحدة فقط لتغير قيمة الثابت . استخدم constant Pragma لتعريف ثابت جديد :

use constant PI => 3.141592653589793;

print "degrees is ", PI;
print "sine of 90",sin(PI/2);

# غير مناسب ان يتم تعديل قيمة المتغير  
$PI = 3; # produces 'Modification of a read-only value attempted ...'

كذلك نفس الشي لإعلان عن مصفوفات وهاشات ثابتة

use constant WEEKDAYS=>('Monday', 'Tuesday', 'Wednesday', 'Thursday'', ‘Friday');
print "The third day is", WEEKDAYS[2];   #ERROR: syntax error
print "The third day is", (WEEKDAYS)[2];   # works ok 

الوحدة البرمجية constant تسبب لإعادة قائمة من القيم الى WEEKDAYS التي ليست بمصفوفة لذا لايمكن استرجاع العناصر بواسطة الفهرس ،يتوجب من اضافة علامات الحصر لجعل القائمة المعادة قابلة للفهرسه .نفس الشيء مع الهاش الثابت لذلك فان القيم المخزنة تعاد كاقائمة ولايمكن الوصول من خلال الفهرس key بدون ان نقوم اولاُ بنقلة الى هاش حقيقي

use constant WEEKABBR => (
Monday=>'Mon', Tuesday=>'Tue', Wednesday=>'Wed',
Thu=>'Thursday', Fri=>'Friday'
);
my %abbr = WEEKABBR;
my $day = 'Wednesday';
print "The abbreviation for $day is ", $abbr{$day};

هذة المشكلة يمكن ان تحل بتعريف مرجع الى الهاش الثابت الذي يحتفظ بالهاش الحقيقي ثم عمل له dereference للوصول الى القيمة الاصلية بهذة الطريقة

use constant WEEKDAYS=>[ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'];
print "The third day is ", WEEKDAYS->[2];

السياق

مفهوم مهم في البيرل فكره تقدير السياق ،وقد يكون السياق في متغير البيرل او أي قسم كالمصوفة وغيرها ، ويشير الى نوع القيمة المطلوبه في حالة المعطى ، فالبيرل لديها ثلاثة سياقات مختلفة وهي scalar و list و void ، والتي تعتمد على الطريقة التي فيها القيمة مستعمله ، ففي scalar context فسوف يطلب متغير واحد فقط ، بينما list context يطلب قائمة من القيم (سواء بدون قيمة او مع العديد من القيم )، واخيراً عندما لاتوجد قيمة في السياق من اي نوع وتسمى بالـ void context .

لمشاهدة الاختلافات ،هنا مثال من قائمة لثلاثة قيم تستعمل في التخصيص :

$count = (1,2,3); # scalar context - counts the elements
@array = (1,2,3); # list context - assigns @INC to another array

ان قائمة الثلاث القيم مقدره في scalar context في اول تخصيص ، و list context في ثاني تخصيص ، وفي كل الحالتين الناتج من التخصيص بأنفسهم هو في void context. ولجعل هذا اوضح في المثال التالي فعلى الطرف الايسر الابعد في التخصيص هو void context ، ولكن على الطرف الايمن الابعد في list context (وهي تقدر اولاًُ ونتيجتها مستعمله بتخصيص الطرف الايسر الابعد ):

@array2 = @array1 = (1,2,3)

العديد من الدوال في البيرل تتفاعل بشكل مختلف عندما تستدعي في مختلف السياقات، فعلى سبيل المثال الدالة localtime فعند استعمال الدالة في scalar context فسوف تعيد النصوص التي تحوى على الوقت الحالى و التأريخ ، بينما عند استعمالها في list context سوف تعيد النصوص التي تحتوي (seconds, minutes, hours, ...الى غير ذلك ) ولاجبار scalar context نستعمل دالة scalar التي هي مفيدة لطباعة الوقت

print "The time is ",localtime,"\n";

ماعدا ذلك سيكون list context:

#!/usr/bin/perl
# time.pl
use warnings;

# a bare block definition
{
    # define six scalars in new block scope:
    my ($sec, $min, $hour, $day, $month, $year) = localtime();
    # variables exist and can be used inside block
    print "The time is: $hour:$min.$sec \n";
    $month++;
    $year += 1900;
    print "The date is: $year/$month/$day \n";
    # end of block - variable definitions cease to exist
}

# produces 'uninitialized value' warning - $sec does not exist here
print "$sec seconds \n";

في البداية تعريف بلوك مجرد bare block ، ويتضمن فيه المتغيرات المحلية ،وتعريف سته متغيرات في list context من خلال الدالة localtime ، التي سوف تعيد الوقت واليوم والشهر والسنة وتخصيصها الى المتغيرات الستة ،وعند الخروج من البلوك الـ bare فأن المتغيرات سوف تهدم ، ولو طباعنا $sec خارج البلوك ستشير البيرل الى تحذير بأن هذا المتغير غير موجود


Warnings & strict

تقوم بتجميع البرنامج باستعمال قيود وقواعد strict

use strict;  # pragmatic module

حيث يقوم بطلب كل المتغيرات لكي تعلن مع الدالة my قبل ان يستعملوا لتمكين فحص الاضافات على الكود التي يجب ان تمر الي التجميع قبل الترجمه والتنفيذ ،فاستعمال my قد يكون مزعج بعض الشيء لكنه يستطيع ان يمسك العديد من البرمجه الخاطئه bugs عند التصريح عن المتغيرات ( bug تعني ان البرنامج سيتنفذ بشكل سليم لكن عند ادخال قيمة ما فانة يظهر الخطأ يسمى bug )

هناك ثلاث انماط للقيود المتبعة في البرنامج وهم vars, refs, subs :

النمط vars فهو يفرض الأعلان عن المتغير مع my ،والنمط refs يمنع المراجع الرمزية ،أما النمط subs يمنع من استعمال الدوال بدون علامات حصر أو & في المقدمه .

وعند أستخدام وحـدة strict بدون وسيط فسوف يعطينا الثلاثه وايضاً يمكننا التمكين وعدم التمكين لكل نمط اذا اردت ذلك

use strict; # استخدام جميع القيود للفحص
use strict qw(vars refs subs); # نفس الشىء ، لكن بطريقة واضحة
no strict qw(refs); #السماح للمراجع الرمزية 

ايضاً البيرل تسمح bareword التي تعني بعدم تضمين اي من علامات الاقتباس ولمنع هذة التأثير باستخدام strict للدالة بواسطة النمط 'subs'

my $a = bareword;
print $a;   #prints "bareword";

Warnings فهي ايضاً لتمكن رسائل التحذير كالخيار –w اما باسطر الاوامر او على البرنامج

> perl -w myscript.pl
#!/usr/bin/perl -w

اكثر تحديداً

#!/usr/bin/perl
use warnings;   # pragmatic module


معاملات الافتباس Quotes

في البرنامج يمكن ان تكتب الاقتباسات باشكال مختلفة ، وكلاً منها تعمل بشكل صحيح في طرق مختلفة ومن تلك الاشكال:


الناتج المعامل نوع الافتباس
حرف نصي q Single quotes
حروف نصية qq Double quotes
حروف بالتعابير المنتظمة qr N/A
لتنفذ برنامج خارجي qx Backticks (``)
قائمة من الكلمات qw N/A


'Literal Text' # مكافئة q(Literal Text)
"$interpolated @text" # مكافئة qq($interpolated @text)
`./external -command` # مكافئة qx(./external -command)

مثال :

#!/usr/bin/perl -w
use strict;
my $text = q/a string with 'quotes' is 'ok' inside q/;
print $text;

ولاحظ في كثير من الحالات ان البيرل يمكن ان تقبل المحددات في المعامل كالـ ( ) او < > او [ ] او { }

$text = qq{ "$interpolated" ($text) 'and quotes too' }; 

المعامل qr يستعمل لتعابيرالمنتظمة

#مباشر
$text =~ /pattern/;

# عن طريق 'qr':
$re = qr/pattern/;
$text =~ $re;

حيث ان المعامل qr يترجم قبل التجميع وهو مفيد في البيرل فيما بعد سيتم ذكره

اما المعامل qx لتنفيذ برنامج اخر

#!/usr/bin/perl
use strict;
use warnings;
my $dir = "/home";
my $files = `ls -1 $dir`; # نفس  my $files = qx(ls -1 $dir);   
#للوندوز `dir c:` 
print $files;

المعامل qw

@array = ('a', 'lot', 'of', 'quotes', 'is', 'not', 'very', 'legible');
@array = qw(a lot of quotes is not very legible);

القيمة الغير معرفة

اولاً علينا ملاحظة إمكانية أن :

من هذة الملاحظات علينا التفريق بين المحتويات ،توفر البيرل الدالة defined لإجراء اختبار لقيمة المتغير او الهاش او المصفوفة لمعرفة من منها قيم معرفة ، لكن لاحظ في تعريف المتغير بالعدد '0' (NULL) او النص فارغاً ذلك يشير الى ان القيمة فارغة وغالباً تعبر عنها الدالة defined بقيمة موجودة

$scalar1='';
print "It is defined!" if defined $scalar1;

القيمة الغير معرفة undef ليست نوع من البيانات قد تاتي مع الكلscalar, list, hash او الانواع الاخرى من البيانات فهي تكافى NULL في لغه السي ، فالقيمة التي لايوجد لديها عناصر بشكل واضح تخصص بالقيمه غير معرفة بإستخدام الكلمه المحجوزه undef أو ضمنياً من خلال الاعلان عنها فقط

$scalar2=undef; #explicitly واضحاً
$scalar2;       #implicitly ضمنياً


الكلمة المحجوزه undef هي ايضاًُ دالة او لاكثر دقةَ هي دالة واحياناً تستخدم لاعادة قيمتها الغير معرفة ،وايضاً هناك طريقة مكافئة لكتابة الاجراء :

print "It is undefined!" if undef $scalar2;
print "It is undefined!" if !defined $scalar2;

لإجراء إختبار المفتاح لمعرفة تواجدة في الهاش توفر البيرل الدالة exists التي تعمل عملية بحث للمفتاح المحدد

%hash = ('A Key' => 'A Value', 'Another Key' => 'Another Value');
print "It exists!" if exists $hash{'A Key'};

يوضح المثال التالي استخدام الدالتين exists و defined

#!/usr/bin/perl
# exists.pl
use strict;
use warnings;

my %hash = ('Key1' => undef, 'Key2' => 'Value2');
my $key = 'Key1';

# the first if tests for the presence of the key 'Key1'
# the second if checks whether the key 'Key1' is defined
if (exists $hash{$key}) {
    if (defined $hash{$key}) {
        print "$key exists and is defined as $hash{$key} \n";
    } else {
        print "$key exists but is not defined \n";
    }
} else {
    print "$key does not exist\n";
}

متغيرات البيئة

عندما تبدأ البيرل او اي اسكربت في اليونكس ، يستلزم وجود متغيرات Env التي توضع مسبقاً لكي تشتغل والا ليس بإمكان ان تبدأ البيرل أو إسكربتات اليونكس ، هذة المتغيرات مثل USER التي تحوي اسم المستخدم و DISPLAY التي تحوي الواجهه التي تسعملها

#!/usr/bin/perl
print "You are called $ENV{'USER'} and you are ";
print "using display $ENV{'DISPLAY'}\n";

فعند تشغل اسكربت CGI على موقع في الانترنت مثلاً سيكون هناك متغيرات Env تقوم بتحمل هذه المعلومات ،وكل هذه المتغيرات وقيمها ستخزن في مصفوفة مترابطه %ENV التي فهارسها ( keys) هي اسماء المتغيرات

#!/usr/bin/perl 
use strict;
foreach my $variable (keys %ENV) {
print "$variable is $ENV{$variable}\n";
}